package com.quanxi.qxaimain.controller.v1.cleaner;

import com.alibaba.fastjson.JSONObject;
import com.quanxi.qxaimain.common.globalException.ResponseVo;
import com.quanxi.qxaimain.common.globalException.ResultCode;
import com.quanxi.qxaimain.dao.SDQuery.SDQueryMapper;
import com.quanxi.qxaimain.dao.cleaner.CleanerMapper;
import com.quanxi.qxaimain.dao.insertDemo.insertDemoMapper;
import com.quanxi.qxaimain.model.doctoradivce.CleanDoctorAdvice;
import com.quanxi.qxaimain.model.doctoradivce.DoctorAdviceKeyword;
import com.quanxi.qxaimain.service.SDQueryService.SDQueryResultHandler;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.java.Log;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;



import java.util.regex.*;


/**
 * @author Liang Zhang
 * @date 2020/05/27
 */

@RestController
@RequestMapping("/dataPreprocess")
@Api(tags = "数据处理")
@Slf4j
public class CleanerController {
    @Resource
    private CleanerMapper yizhuCleanerMapper;
    // private final static int BATCH_SIZE = 10000;

    @Resource
    private com.quanxi.qxaimain.dao.SDQuery.SDQueryMapper SDQueryMapper;

    @Autowired
    com.quanxi.qxaimain.dao.insertDemo.insertDemoMapper insertDemoMapper;

    @PostMapping("/dataClean")
    @ApiOperation(value = "数据清洗", httpMethod = "POST")
    public JSONObject dataClean(@RequestBody JSONObject params) throws ParseException, IOException  {
        Map<String, Object> result;
        JSONObject jsonObj;

        String str1 = params.getString( "startDate");
        String str2 = params.getString( "endDate");
        String keyWord = params.getString( "keyWord");
        int classNo = params.getIntValue("classNo");

        String typeCode = params.getString(("typeCode"));

//      String str3="PROCQXZSKNEWSJZB1";
//      String str4="PROCQXZSKNEWSJZB2";

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Date date1 = df.parse(str1);
        Date date2 = df.parse(str2);

        Date sysdate = Calendar.getInstance().getTime();

        if (date2.getTime() > sysdate.getTime()) {

            // yizhuCleanerMapper.updateCleanFlag(date1, date2);

            result = new HashMap<>();
            ResponseVo obj = new ResponseVo(ResultCode.END_DATE_NOT_ALLOWED.getCode(), ResultCode.END_DATE_NOT_ALLOWED.getMsg(),"");
            result.put("msg", obj);
            jsonObj = new JSONObject(result);
            return jsonObj;
        }

        List<Object> objectList = new ArrayList<>();
        Map<String, Object> map;
        List<Object> tempObjectList;
        int batchSize;

        map = new HashMap<>();
        map.put("ORGAN_ID", "康宁医院");
        map.put("D1", date1);
        map.put("D2", date2);

        if (typeCode.equals("1")) {
            List<DoctorAdviceKeyword> keyWordFlag1Arr = yizhuCleanerMapper.findYizhuKeyWordWithFlag1();
            List<DoctorAdviceKeyword> keyWordFlag0Arr = yizhuCleanerMapper.findYizhuKeyWordWithFlag0();
            batchSize = 1000;
            cleanYizhuCoreFunction(keyWordFlag1Arr, keyWordFlag0Arr, str1, str2, batchSize);
            yizhuCleanerMapper.updateCleanFlag(date1, date2);
        }
        else if (typeCode.equals("2")) {
            //选择医嘱表中的类编号来清洗医嘱
            List<DoctorAdviceKeyword> keyWordFlag1Arr = yizhuCleanerMapper.findYizhuKeyWordByClassNoWithFlag1(classNo);
            List<DoctorAdviceKeyword> keyWordFlag0Arr = yizhuCleanerMapper.findYizhuKeyWordByClassNoWithFlag0(classNo);
            batchSize = 5000;
            if (keyWordFlag1Arr.size() > 0)
                cleanYizhuCoreFunction(keyWordFlag1Arr, keyWordFlag0Arr, str1, str2, batchSize);
        }
        else if (typeCode.equals("3")) {
            //自定义医嘱关键字和类编号来添加清洗的医嘱
            DoctorAdviceKeyword dkw = new DoctorAdviceKeyword();
            dkw.setKeywordName(keyWord);
            dkw.setClassNo(classNo);
            List<DoctorAdviceKeyword> keyWordFlag1Arr = new ArrayList<>();
            List<DoctorAdviceKeyword> keyWordFlag0Arr = new ArrayList<>();
            keyWordFlag1Arr.add(dkw);
            batchSize = 5000;
            cleanYizhuCoreFunction(keyWordFlag1Arr, keyWordFlag0Arr, str1, str2, batchSize);
        }
        else if (typeCode.equals("4")) {
            //删除所有标签为Class_No的清洗医嘱
            yizhuCleanerMapper.deleteYizhuByClassNo(classNo);
        }

        result = new HashMap<>();
        ResponseVo obj = new ResponseVo(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(),"");
        result.put("msg", obj);
        jsonObj = new JSONObject(result);
        return jsonObj;
    }

    public void insertCleanedDataFromYizhuList(List<Map> yizhuResArr, Map<String, CleanDoctorAdvice>cleanDocAdvMap,
                                               List<DoctorAdviceKeyword> keyWordFlag1Arr, List<DoctorAdviceKeyword> keyWordFlag0Arr,
                                               List<CleanDoctorAdvice> cleanDocAdvArr) {
        for (Map<String, Object> doc_adv : yizhuResArr) {
            int start = cleanDocAdvMap.size();
            for (DoctorAdviceKeyword doc_adv_kw : keyWordFlag1Arr) {
                String content = doc_adv.get("DOC_ADV_DETAIL_NAME").toString();
                String pattern = ".*" + doc_adv_kw.getKeywordName() + ".*";
                boolean isMatch = Pattern.matches(pattern, content);
                if (isMatch) {
                    CleanDoctorAdvice obj = new CleanDoctorAdvice(doc_adv.get("DOC_ADV_ID").toString(), doc_adv.get("INPATIENT_VISIT_FORM_NO").toString(),
                            doc_adv.get("DOC_ADV_DETAIL_NAME").toString(), doc_adv_kw.getClassNo(), 1);
                    String key = doc_adv.get("DOC_ADV_ID").toString() + "_" + doc_adv_kw.getClassNo();
                    cleanDocAdvMap.put(key, obj);
                }
            }
            int end = cleanDocAdvMap.size();

            //得到不重复的flag被统一设成了1的清洗过的医嘱
            List<CleanDoctorAdvice> tempList = new ArrayList<>(cleanDocAdvMap.values());
            //到这一步后原先的Map没什么用(弃用)了，处理这个List即可

            //搜索flag=0的条目并把符合要求的清洗过的医嘱的flag由1变为0
            for (int i = start; i < end; i++) {
                CleanDoctorAdvice cda = tempList.get(i);
                for (DoctorAdviceKeyword doc_adv_kw : keyWordFlag0Arr) {
                    if (cda.getClass_no() == doc_adv_kw.getClassNo()) {
                        String content = cda.getDoc_adv_detail_name();
                        String pattern = ".*" + doc_adv_kw.getKeywordName() + ".*";
                        boolean isMatch = Pattern.matches(pattern, content);
                        if (isMatch) {
                            cda.setFlag(0);
                            break;
                        }
                    }
                }
                cleanDocAdvArr.add(cda);
            }
        }

        if (cleanDocAdvArr.size() > 0) {
            yizhuCleanerMapper.deleteYizhuBatch(cleanDocAdvArr);
            yizhuCleanerMapper.insertYizhuBatch(cleanDocAdvArr);
        }
        log.info(cleanDocAdvArr.size() + "条数据已被添加");
    }

    public void cleanYizhuCoreFunction (List<DoctorAdviceKeyword> keyWordFlag1Arr, List<DoctorAdviceKeyword> keyWordFlag0Arr, String start_str, String end_str, int batchSize) throws ParseException {

        Map<String, CleanDoctorAdvice> cleanDocAdvMap = new LinkedHashMap<>();
        List<CleanDoctorAdvice> cleanDocAdvArr = new ArrayList<>();

        String sql = "select t.inpatient_visit_form_no, t.doc_adv_id, t.doc_adv_order_date, t.doc_adv_detail_name, t.doc_adv_order_name \n" +
                " from QXNEWDBNYDSZYY.TB_CIS_DRADVICE_DETAIL t where t.sysup_time BETWEEN to_date(' " +
                start_str + " ','yyyy-mm-dd hh24:mi:ss') AND to_date(' " + end_str + " ','yyyy-mm-dd hh24:mi:ss')";
        SDQueryResultHandler sdQueryResultHandler = new SDQueryResultHandler() {
            int counter = 0;

            @Override
            public void handle() {
                try {
                    counter += list.size();
                    log.info("-------:{}条数据已被处理", counter);
                    //list为批量查询结果集,对此list进行业务处理

                    insertCleanedDataFromYizhuList(list, cleanDocAdvMap, keyWordFlag1Arr, keyWordFlag0Arr, cleanDocAdvArr);
                } catch (Exception  e){
                    log.info(e.getMessage()+"===========error==========");
                }finally {
                    // 处理完每批数据后后将临时清空
                    size = 0;
                    list.clear();

                    cleanDocAdvMap.clear();
                    cleanDocAdvArr.clear();
                }

            }

            @Override
            public Map singlehandle(Map map) {
                //处理每条数据
                //   log.info("---------------------:{}",map.get("DOC_ADV_DETAIL_NAME")+"9999999");
                //   map.put("DOC_ADV_DETAIL_NAME","CleanFinish"+map.get("DOC_ADV_DETAIL_NAME"));
                return map;
            }

            @Override
            public void tryFetchData() {
                SDQueryMapper.streamDataDynamicHandle(sql,this);
            }
        };

        sdQueryResultHandler.setBatchSize(batchSize); //设置批处理数
        sdQueryResultHandler.start();
        sdQueryResultHandler.lastSDHandle();// 批处理余数

//        //查看医嘱
//        List<Map> yizhuResArr= new ArrayList<>();
//        Map<String, CleanDoctorAdvice> cleanDocAdvMap = new LinkedHashMap<>();
//        List<CleanDoctorAdvice> cleanDocAdvArr = new ArrayList<>();
//
//        log.info("start");
//        yizhuCleanerMapper.findYizhuStream(new ResultHandler<Map<String,Object>>() {
//            @Override
//            public void handleResult(ResultContext<? extends Map<String,Object>> resultContext) {
//                Map<String,Object> map = resultContext.getResultObject();
//                yizhuResArr.add(map);
//                if (yizhuResArr.size() == batchSize ) {
//                    //处理医嘱
//                    log.info(resultContext.getResultCount() + "条医嘱已被读取");
//                    insertCleanedDataFromYizhuList(yizhuResArr, cleanDocAdvMap, keyWordFlag1Arr, keyWordFlag0Arr, cleanDocAdvArr);
//                    yizhuResArr.clear();
//                    cleanDocAdvMap.clear();
//                    cleanDocAdvArr.clear();
//                }
//            }
//        }, date1, date2);
//
//        if(yizhuResArr.size() > 0)
//            insertCleanedDataFromYizhuList(yizhuResArr, cleanDocAdvMap, keyWordFlag1Arr, keyWordFlag0Arr, cleanDocAdvArr);
//
//        // 更新IS_CLEANED标识
//        yizhuCleanerMapper.updateCleanFlag(date1, date2);

    }

//    @PostMapping("/dataCleanFromKettle")
//    @ApiOperation(value = "数据清洗", httpMethod = "POST")
//    public int dataCleanFromKettle(@RequestBody JSONObject params) throws ParseException {
//        JSONObject data = params.getJSONArray("data").getJSONObject(0);
//        String inpatientVisitFormNo = data.getString("INPATIENT_VISIT_FORM_NO");
//        String docAdvId = data.getString("DOC_ADV_ID");
//        String docAdvDetailName = data.getString("DOC_ADV_DETAIL_NAME");
//        log.info(docAdvId);
//        log.info(inpatientVisitFormNo);
//        log.info(docAdvDetailName);
//
//        List<DoctorAdviceKeyword> li = yizhuCleanerMapper.findYizhuKeyWordWithFlag1();
//        for (DoctorAdviceKeyword doctorAdviceKeyword : li) {
//            yizhuCleanerMapper.insertSingleYizhu(docAdvId, inpatientVisitFormNo, docAdvDetailName,
//                    '%' + doctorAdviceKeyword.getKeywordName() + '%', doctorAdviceKeyword.getClassNo());
//        }
//        List<DoctorAdviceKeyword> li2 = yizhuCleanerMapper.findYizhuKeyWordWithFlag0();
//        for (DoctorAdviceKeyword doctorAdviceKeyword : li2) {
//            yizhuCleanerMapper.updateSingleYizhuWithFlag0(docAdvId, inpatientVisitFormNo, docAdvDetailName,
//                    '%' + doctorAdviceKeyword.getKeywordName()+ '%', doctorAdviceKeyword.getClassNo());
//        }
//        return 1;
//    }
}
